import { isObject, extend } from '../shared';
import { track, trigger } from './effect'
import { ReactiveFlags, reactive, readonly } from './reactive'

// 利用缓存，初始化的时候立即创建 get set
const get = createGetter();
const set = createSetter();
const readonlyGet = createGetter(true);
const shallowReadonlyGet = createGetter(true, true);

/**
 * 创建一个 get 函数 （高阶函数，二次封装）
 * @param isReadOnly 是否为 readonly 对象
 * @returns 
 */
function createGetter(isReadOnly = false, isShallow = false) {
    return function get(target, key) {
        
        // 处理 isRadonly, isReactive 获取时的数据
        if (key === ReactiveFlags.IS_READONLY && isReadOnly) {
            return true;
        }
        if (key === ReactiveFlags.IS_REACTIVE && !isReadOnly) {
            return true;
        }

        // target -> {foo:1}
        // key : foo
        const res = Reflect.get(target, key);

        // 实现嵌套多层 reactive, 和 多层 readonly
        // !isShallow -> 只有在取多层的时候才能进行多层向下转换， isShallow 只取第一层
        if (isObject(res) && !isShallow)
            return isReadOnly ? readonly(res) : reactive(res);

        if (!isReadOnly) {
            // 不是 readonly 才收集依赖
            ///  TODO: 依赖收集
            track(target, key);
        }
        return res;
    };
}

/**
 * 创建一个 set 函数 （高阶函数，二次封装）
 * @returns 
 */
function createSetter() {
    return function set(target, key, value) {
        const res = Reflect.set(target, key, value);

        /// TODO: 触发依赖，依赖调用
        trigger(target, key);
        return res;
    };
}

/**
 * reactive 的 get set （可变类型）
 */
export const mutableHandlers = {
    get,
    set
}


/**
 * readonly 的 get （只读类型）
 */
export const readonlyHandlers = {
    get: readonlyGet,
    set(target, key, value) {
        console.warn(`readonly 对象不能被修改值，key${key as string} set 失败，触发警告！`);
        return true;
    }
}


/**
 * shallowReadonly 的 get （只读类型，浅层readonly，非嵌套转换）
 */
export const shallowReadonlyHandlers = extend({}, { get: shallowReadonlyGet, set: readonlyHandlers.set });
